// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.snackbar;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;

import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardExtensionSizeManager;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener;
import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver;

/**
 * The container that holds both infobars and snackbars. It will be translated up and down when the
 * bottom controls' offset changes.
 */
public class BottomContainer
        extends FrameLayout implements FullscreenListener, KeyboardExtensionSizeManager.Observer {
    /** The {@link ChromeFullscreenManager} to listen for controls offset changes. */
    private ChromeFullscreenManager mFullscreenManager;

    /** A {@link KeyboardExtensionSizeManager} to listen to for keyboard extension size changes. */
    private KeyboardExtensionSizeManager mKeyboardExtensionSizeManager;

    /** The desired Y offset if unaffected by other UI. */
    private float mBaseYOffset;

    /** The offset generated by the {@link BottomSheet} showing. */
    private float mOffsetFromSheet;

    /**
     * Constructor for XML inflation.
     */
    public BottomContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * Initializes this container.
     */
    public void initialize(ChromeFullscreenManager fullscreenManager,
            KeyboardExtensionSizeManager keyboardExtensionSizeManager) {
        mFullscreenManager = fullscreenManager;
        mFullscreenManager.addListener(this);
        mKeyboardExtensionSizeManager = keyboardExtensionSizeManager;
        mKeyboardExtensionSizeManager.addObserver(this);
        setTranslationY(mBaseYOffset);
    }

    /**
     * @param sheet The {@link BottomSheet} that interacts with this container.
     */
    public void setBottomSheet(BottomSheet sheet) {
        sheet.addObserver(new EmptyBottomSheetObserver() {
            @Override
            public void onSheetOffsetChanged(float heightFraction, float offsetPx) {
                // We only care about the height of the bottom sheet between its hidden and peeking
                // state (the UI should stack). Once the sheet is opened, the bottom container
                // stays in place, becoming obscured by the sheet.
                if (heightFraction > sheet.getPeekRatio()) return;
                mOffsetFromSheet = -(sheet.getSheetContainerHeight() * heightFraction);
                // Only apply the shadow height if the sheet is actually visible.
                if (heightFraction > 0) mOffsetFromSheet += sheet.getToolbarShadowHeight();
                setTranslationY(mBaseYOffset);
            }
        });
    }

    // KeyboardExtensionSizeManager methods
    @Override
    public void onKeyboardExtensionHeightChanged(int keyboardHeight) {
        setTranslationY(mBaseYOffset);
    }

    // FullscreenListener methods
    @Override
    public void onControlsOffsetChanged(int topOffset, int bottomOffset, boolean needsAnimate) {
        setTranslationY(mBaseYOffset);
    }

    @Override
    public void setTranslationY(float y) {
        mBaseYOffset = y;

        float offsetFromControls = mFullscreenManager.getBottomControlOffset()
                - mFullscreenManager.getBottomControlsHeight();
        offsetFromControls -= mKeyboardExtensionSizeManager.getKeyboardExtensionHeight();

        // Sit on top of either the bottom sheet or the bottom toolbar depending on which is larger
        // (offsets are negative).
        super.setTranslationY(mBaseYOffset + Math.min(offsetFromControls, mOffsetFromSheet));
    }

    @Override
    public void onBottomControlsHeightChanged(int bottomControlsHeight) {
        setTranslationY(mBaseYOffset);
    }

    @Override
    public void onContentOffsetChanged(int offset) {}

    @Override
    public void onToggleOverlayVideoMode(boolean enabled) { }
}
